﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using F1010DB.Constant;
namespace F1010DB.Common
{
    public static class ValidationHelper
    {
        private const string NUMERIC_PARTERN = @"^(0|[0-9][0-9]*)$";
        private const string NUMERIC_DECIMAL_PARTERN = @"(^(\+?\-? *[0-9]+)([.0-9]*)([0-9])*$)|(^ *$)";
        private const string EMAIL_PARTERN = @"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$";
        
        public static class ValidationForString
        {
            private  static char[] NONE_ALPHABERT= {'!','@','#','$','%',':','%','^','&','*','(',')','~'};

            public static string checkMaxLength(string value, int max)
            {
                return  value != null && value.Length <= max ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000006;
            }

            public static string checkMinLength(string value, int min)
            {
                return value != null && value.Length >= min ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000007;
            }

            public static string checkWithinLength(string value, int min, int max)
            {
                return value != null && value.Length >= min && value.Length <= max ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000008;
            }

            public static string checkEmail(string value)
            {
                return value != null && Regex.IsMatch(value, EMAIL_PARTERN) ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000009;
            }

            public static string checkPhone(string value)
            {
                if (!Regex.IsMatch(value, NUMERIC_PARTERN))
                {
                    return ConstantForMsgId.CONST_V000005;
                }
                else if (value.Length != 10 && value.Length != 11 && value.Length !=12)
                {
                    return ConstantForMsgId.CONST_V000010;
                }
                return ConstantForMsgId.CONST_NONE;
            }

            public static string checkSoCMND(string value)
            {
                bool isTruth =  Regex.IsMatch(value, NUMERIC_PARTERN) && (value.Length == 9 || value.Length == 12);
                return isTruth ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000011;
            }

            public static string checkRequire(string value)
            {
                return value != null && value.Length != 0 || String.IsNullOrEmpty(value) == false ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000001;
            }

            public static string checkLengthRequire(string value, int len)
            {
                return value != null && value.Length == len ? ConstantForMsgId.CONST_NONE : ConstantForMsgId.CONST_V000012;
            }

            public static string checkLengthOr(string value, int len1, int len2)
            {
                return value != null && value.Length == len1 || value.Length == len2 ? ConstantForMsgId.CONST_NONE : "V000020";
            }
            public static string checkAlphanumeric(string value)
            {
                char[] c = value.ToCharArray();

                foreach(char t in c)
                {
                    if (Array.IndexOf(NONE_ALPHABERT, c) != -1)
                    {
                        return ConstantForMsgId.CONST_V000004;
                    }
                }

                return ConstantForMsgId.CONST_NONE;
            }
        }

        public static class ValidateForDate
        {
            private static int[] FULL_MONTH = {1,3,5,7,8,10,12};
            private static  int[] NOT_FULL_MONTH = {4,6,9,11};
            
            /// <summary>
            /// Kiểm tra format ngày tháng năm
            /// </summary>
            /// <param name="yr"></param>
            /// <param name="mth"></param>
            /// <param name="dy"></param>
            /// <returns></returns>
            public static string checkDate(string yr, string mth, string dy)
            {
                string codId = ConstantForMsgId.CONST_NONE;

                //Kiểm tra có phải là số không
                if (!Regex.IsMatch(yr, NUMERIC_PARTERN) || !Regex.IsMatch(mth, NUMERIC_PARTERN) || !Regex.IsMatch(dy,NUMERIC_PARTERN))
                {
                    return ConstantForMsgId.CONST_V000003;
                }

                //Kiểm tra coi xem chiều dài các ngày, tháng, năm có phù hợp không
                if (ValidationForString.checkLengthRequire(yr, 4) != ConstantForMsgId.CONST_NONE
                    || ValidationForString.checkLengthOr(mth,2,1) != ConstantForMsgId.CONST_NONE 
                    || ValidationForString.checkLengthOr(dy,2,1) != ConstantForMsgId.CONST_NONE)
                {
                    return ConstantForMsgId.CONST_V000003;
                }

                // Kiểm tra format
                int intYear = Int16.Parse(yr);
                int intMonth = Int16.Parse(mth);
                int intDay = Int16.Parse(dy);

                // Kiểm tra tháng 1 ~ 12
                if (intMonth < 1 || intMonth > 12)
                {
                    return ConstantForMsgId.CONST_V000003;
                }
                // Nếu ngày nhỏ hơn 1
                if (intDay < 1)
                {
                    return ConstantForMsgId.CONST_V000002;
                }

                // Kiểm tra những ngày trong tháng có số ngày 1 ~ 30
                if (Array.IndexOf(FULL_MONTH, intMonth) != -1)
                {
                    if (intDay > 31)
                    {
                        return ConstantForMsgId.CONST_V000002;
                    }
                } 
                else if (Array.IndexOf(NOT_FULL_MONTH, intMonth) != -1)
                {
                    if (intDay > 30)
                    {
                        return ConstantForMsgId.CONST_V000002;
                    }
                }
                
                // Xét năm nhuận
                if (intYear % 4 == 0 || (intYear % 100 == 0 && intYear % 400 == 0))
                {
                    if (intDay > 28)
                    {
                        return ConstantForMsgId.CONST_V000002;
                    }
                }

                if (intDay > 29)
                {
                    return ConstantForMsgId.CONST_V000002;
                }

                return codId;
            }
        }

        public static bool isNumeric(string value)
        {
            return Regex.IsMatch(value, NUMERIC_DECIMAL_PARTERN) || Regex.IsMatch(value, NUMERIC_PARTERN);
        }
        
        public static bool isCheckStringWithin(string value, string[] withinValue)
        {
            return Array.IndexOf(withinValue, value) >= 0;
        }

        public static bool hasError(string key)
        {
            return !key.Equals(Constant.ConstantForMsgId.CONST_NONE);
        }
    }
}
